home *** CD-ROM | disk | FTP | other *** search
- unit HugeUtil;
-
- interface
-
- const HugeMax = $8000-16;
-
- type Huge = record
- len : word;
- dat : array[1..HugeMax] of word;
- end;
- HugePtr = ^Huge;
-
- procedure AddHuge (var Answer, Add : Huge);
- procedure MulHuge (var A : Huge; Mul : integer; var Answer : Huge);
- procedure DivHuge (var A : Huge; Del : integer; var Answer : Huge;
- var Remainder : integer);
- procedure SubHuge (var Answer, Sub : Huge);
- procedure ZeroHuge (var L : Huge; Size : word);
- procedure CopyHuge (var Fra,Til : Huge);
- procedure GetHuge (var P : HugePtr; Size : word);
- procedure WriteHuge(var L : Huge; Size: word);
-
- implementation
-
- procedure AddHuge; assembler; asm
- cld
- push ds
- lds di,Answer
- les si,Add
- seges lodsw
- mov cx,ax
- clc
- @l1:
- seges lodsw
- adc [si-2],ax
- loop @l1
- jnb @done
- @l2:
- add word [si],1
- inc si
- inc si
- jc @l2
- @done:
- mov si,di
- lodsw
- shl ax,1
- add si,ax
- lodsw
- or ax,ax
- je @d2
- inc word [di]
- @d2:
- pop ds
- end;
-
- procedure MulHuge; assembler; asm
- cld
- push ds
- lds si,A
- mov bx,Mul
- les di,Answer
- mov cx,[si]
- mov dx,si
- inc di
- inc di
- clc
- @l1:
- mov ax,[di]
- pushf
- mul bx
- popf
- adc ax,si
- stosw
- mov si,dx
- loop @l1
- adc si,0
- mov es:[di],si
- lds di,A
- mov di,[di]
- mov ax,[di+2]
- or ax,ax
- je @l2
- inc di
- inc di
- @l2:
- lds si,Answer
- mov [si],di
- pop ds
- end;
-
- procedure DivHuge; assembler; asm
- std
- push ds
- lds si,A
- mov bx,Del
- les di,Answer
- mov cx,[si]
- mov di,cx
- add di,cx
- xor dx,dx
- @l1:
- mov ax,[di]
- div bx
- stosw
- loop @l1
- lds si,Remainder
- mov [si],dx
- lds si,A
- mov ax,[si]
- lds di,Answer
- mov [di],ax
- mov si,[di]
- shl si,1
- @d3:
- lodsw
- or ax,ax
- jne @d2
- dec word [di]
- jne @d3
- inc word [di]
- @d2:
- pop ds
- end;
-
- procedure SubHuge; assembler; asm
- cld
- push ds
- lds di,Answer
- les si,Sub
- seges lodsw
- mov cx,ax
- clc
- @l1:
- seges lodsw
- sbb [si-2],ax
- loop @l1
- jnb @done
- @l2:
- sub word [si],1
- inc si
- inc si
- jc @l2
- @done:
- mov si,[di]
- shl si,1
- std
- @d3:
- lodsw
- or ax,ax
- jne @d2
- dec word [di]
- jne @d3
- inc word [di]
- @d2:
- pop ds
- end;
-
-
- procedure WriteHuge;
- var L1, L2, I, R, R1, X : integer;
- begin
- with L do begin
- L1 := Len;
- L2 := L1 - 1;
- I := 1;
- write(dat[L1],'.');
- X := 0;
- for I := 1 to Size div 4 do begin
- Dat[L1] := 0;
- Len := L2;
- MulHuge(L,10000,L);
- R := dat[L1];
- R1 := R div 100;
- R := R mod 100;
- write(chr(R1 div 10+48), chr(R1 mod 10+48),
- chr(R div 10+48), chr(R mod 10+48));
- inc(X);
- write(' ');
- if X > 14 then begin
- writeln; write(' ');
- X := 0
- end
- end
- end;
- writeln
- end; { WriteHuge }
-
- procedure ZeroHuge;
- begin
- fillchar(L.Dat, Size * 2, #0);
- L.Len := Size
- end;
-
- procedure CopyHuge;
- begin
- move(Fra, Til, Fra.Len * 2 + 2)
- end;
-
- procedure GetHuge;
- var D : ^byte;
- Tries,
- Bytes : word;
- begin
- Bytes := 2 * (Size + 1);
- Tries:=0;
- repeat
- getmem(P,Bytes);
-
- { To make it possible to use maximally large arrays, and to increase
- the speed of the computations, all records of type Huge MUST start
- at a segment boundary! }
-
- if ofs(P^) = 0 then begin
- ZeroHuge(P^,Size);
- exit
- end;
- inc(Tries);
- freemem(P,Bytes);
- new(D)
- until Tries>10; { if not done yet, it's not likely we ever will be }
- writeln('Couldn''t get memory for array');
- halt(1)
- end; { GetHuge }
-
- end.